<template>
  <Teleport to="body">
    <div :class="cn(toastClass(placement), props.class)">
      <TransitionGroup
        tag="div"
        enter-from-class="opacity-0"
        enter-to-class="opacity-100"
        enter-active-class="transition duration-1000 ease-in"
        leave-from-class="opacity-100"
        leave-to-class="opacity-0"
        leave-active-class="transition duration-500 ease-in"
      >
        <ZAlert
          class="my-2"
          v-for="item in items"
          :key="item.name"
          v-bind="item"
          @close="(name) => (items = items.filter((i) => i.name != name))"
        />
      </TransitionGroup>
    </div>
  </Teleport>
  <slot />
</template>
<script setup lang="ts">
import { ref, provide } from "vue";
import { cva } from "class-variance-authority";

import { cn } from "../../utils";
import type { ToastPlacement, AlertType } from "../types";
import ZAlert from "../ZAlert.vue";

import { ToastInjectKey } from "./useToast";

interface Props {
  placement: ToastPlacement | ToastPlacement[];
  duration?: number;
  class?: string;
}
const props = withDefaults(defineProps<Props>(), {
  duration: 3000,
});

const toastVariants = cva("toast", {
  variants: {
    placement: {
      top: "toast-top",
      middle: "toast-middle",
      bottom: "toast-bottom",
      start: "toast-start",
      end: "toast-end",
      center: "toast-center",
    },
  },
});
// 使用自定义函数处理样式数组
function toastClass(placement: ToastPlacement | ToastPlacement[]): string {
  if (Array.isArray(placement)) {
    return placement
      .map((item) => toastVariants({ placement: item }))
      .join(" ");
  }
  return toastVariants({ placement });
}
// alerts 数组
interface ToastItem {
  type: AlertType;
  name: string;
  title?: string;
  message?: string;
  duration?: number;
}
const items = ref<ToastItem[]>([]);
let id = 0;
function createToast(type: AlertType, defaultTitle: string) {
  return (message: string, options?: { title?: string; duration?: number }) => {
    items.value.push({
      type,
      name: `ZToast-${id++}`,
      title: options?.title ?? defaultTitle,
      message,
      duration: options?.duration ?? props.duration,
    });
  };
}
provide(ToastInjectKey, {
  success: createToast("success", "成功"),
  info: createToast("info", "提示"),
  warning: createToast("warning", "警告"),
  error: createToast("error", "错误"),
});
</script>
